package com.server.http.anYuan;

import com.alibaba.fastjson2.JSONObject;
import com.server.dao.*;
import com.server.http.service.AlarmService;
import com.server.http.service.MobileAppService;
import com.server.http.service.UnitService;
import com.server.libs.login.data.AppCache;
import com.server.libs.login.AppOline;
import com.server.pojo.*;
import com.server.push.AliYunPush;
import com.server.push.OnlinePush;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.net.URLDecoder;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/anYuan")
@Slf4j
@Transactional
public class AnYuanController {
    @Autowired
    MobileAppNoticeDao mobileAppNoticeDao;

    @Autowired
    NoticeDao noticeDao;
    @Autowired
    AlarmDao alarmDao;
    @Autowired
    UnitDao unitDao;


    @Autowired
    MobileAppDao mobileAppDao;

    @Autowired
    MobileAppService mobileAppService;

    @Autowired
    MobileAppUnitDao mobileAppUnitDao;

    @Autowired
    AlarmService alarmService;

    @Autowired
    OnlinePush onlinePush;

    @Autowired
    UnitService unitService;

    @Autowired
    AppOline appOline;


    private Set<String> commids = new HashSet<>();

    @RequestMapping(value = "/alarm/new", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> anYuanAlarm(@RequestBody String text) throws Exception {

        AnYuanDto dto = AnYuanDto.from(text);
        String code = dto.data.getString("uid");
        String commid = dto.data.getString("commid");
        Integer com = dto.data.getInteger("com");

        if (commids.contains(commid)) {
            return dto.NO("已经完成过该操作！");
        }
        Alarm alarm = new Alarm();
        Unit unit = new Unit();
        if (com == 205) { //账号警报处理  直接对数据存储
            MobileApp mobileApp = mobileAppDao.findByAccount(dto.data.getString("uid"));
            alarm.setMobileApp(mobileApp);
            unit = new Unit();
            unit.setIsCanJoin(false);
            unit.setCode(mobileApp.getAccount() + "_" + UUID.randomUUID().toString().replace("-",""));

        } else if (com == 201) { //原警报处理 对单位数据进行统一
            unit = unitDao.findByCode(code);
            if (unit == null) {
                unit = new Unit();
                if (code != null) unit.setCode(code);
            }
        }


        if (dto.data.containsKey("uname")) unit.setName(dto.data.getString("uname"));
        if (dto.data.containsKey("uadd")) unit.setAddr(dto.data.getString("uadd"));
        if (dto.data.containsKey("uman")) unit.setManager(dto.data.getString("uman"));
        if (dto.data.containsKey("utel")) unit.setTel(dto.data.getString("utel"));
        if (dto.data.containsKey("pcs")) unit.setPoliceStation(dto.data.getString("pcs"));
        if (dto.data.containsKey("weidu")) unit.setLatitude(dto.data.getBigDecimal("weidu"));
        if (dto.data.containsKey("jingdu")) unit.setLongitude(dto.data.getBigDecimal("jingdu"));
        unitDao.save(unit);

        alarm.setUnit(unit);
        alarm.setLatitude((dto.data.containsKey("sbweidu") && dto.data.getBigDecimal("sbweidu").doubleValue() != 0) ? dto.data.getBigDecimal("sbweidu") : unit.getLatitude());
        alarm.setLongitude((dto.data.containsKey("sbjingdu") && dto.data.getBigDecimal("sbjingdu").doubleValue() != 0) ? dto.data.getBigDecimal("sbjingdu") : unit.getLongitude());
        if(dto.data.containsKey("popfrom"))alarm.setRing(dto.data.getInteger("popfrom") == 1);
        if(dto.data.containsKey("search"))alarm.setScope(dto.data.getLong("search") > 0 ? dto.data.getLong("search") : null);
        if(dto.data.containsKey("alarmtype"))alarm.setType(dto.data.getInteger("alarmtype"));
        if(dto.data.containsKey("alarmsb"))alarm.setDeviceType(dto.data.getInteger("alarmsb"));
        if(dto.data.containsKey("message"))alarm.setMessage(dto.data.getString("message"));
        if(dto.data.containsKey("sendapp"))alarm.setInform(dto.data.getInteger("sendapp") == 1);
        if(dto.data.containsKey("duration"))alarm.setDuration(dto.data.getLong("duration") * 1000);
        if(dto.data.containsKey("updata"))alarm.setAnYuanPushInterval(dto.data.getLong("updata") * 1000);




        alarmDao.save(alarm);

        if (com == 205) {
            List<String> accounts = Arrays.asList(dto.data.getString("appadmin").split("\\*"));
            List<MobileApp> mobileApps = mobileAppDao.findByAccountIn(accounts);

            alarmService.push(alarm, new HashSet<>(mobileApps));
        } else if (com == 201) {
            alarmService.push(alarm);
        }


        return dto.OK();
    }

    @RequestMapping(value = "/notice/new", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> unitNotice(@RequestBody String text) throws Exception {
        AnYuanDto dto = AnYuanDto.from(text);

        Integer type = dto.data.getInteger("messagetype");
        String val = dto.data.getString("conid");
        String title = dto.data.getString("titlestre");
        String body = dto.data.getString("textstr");
        Integer bodyType = dto.data.getInteger("commtype");
        List<String> fileUrl = dto.data.containsKey("fileurl") ? Arrays.asList(dto.data.getString("fileurl").split(";")) : new ArrayList<>();

        Notice notice = new Notice();
        notice.setTitle(title);
        notice.setBody(body);
        notice.setFileUrls(fileUrl);

        List<MobileApp> mobileApps = new ArrayList<>();

        if (type == 1) {
            mobileApps.addAll(mobileAppDao.findAll());
        } else if (type == 2) {
            Unit unit = unitDao.findByCode(val);
            mobileApps.addAll(mobileAppUnitDao.getMobileApps(unit));
        } else if (type == 3) {
            mobileApps.add(mobileAppDao.findByAccount(val));
        }
        noticeDao.save(notice);

        List<MobileAppNotice> mobileAppNotices = new ArrayList<>();
        mobileApps.forEach(var->{
            MobileAppNotice mobileAppNotice = new MobileAppNotice();
            mobileAppNotice.setNotice(notice);
            mobileAppNotice.setMobileApp(var);
            mobileAppNotices.add(mobileAppNotice);

        });
        mobileAppNoticeDao.saveAll(mobileAppNotices);


        noticeDao.save(notice);


        AliYunPush.notice(mobileApps, notice);

        return dto.OK();
    }


    @RequestMapping(value = "/unit/upload", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> unitUpload(@RequestBody String text) throws Exception {
        AnYuanDto dto = AnYuanDto.from(text);

        String code = dto.data.getString("uid");
        Integer act = dto.data.getInteger("act");

        Unit unit = unitDao.findByCode(code);
        if (act == 1 || act == 2) {
            if (unit == null) {
                unit = new Unit();
            }
            unit.setCode(code);
            unit.setName(dto.data.getString("uname"));
            unit.setAddr(dto.data.getString("uaddr"));
            unit.setTel(dto.data.getString("utel"));
            unit.setManager(dto.data.getString("uman"));
            unit.setPoliceStation(dto.data.getString("pcs"));
            unitDao.save(unit);
        } else if (act == 3 && unit != null) {
            unitDao.delete(unit);
        }

        return dto.OK();
    }

    @RequestMapping(value = "/unit/position", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> unitLatLng(@RequestBody String text) throws Exception {
        AnYuanDto dto = AnYuanDto.from(text);

        String code = dto.data.getString("uid");

        Unit unit = unitDao.findByCode(code);
        if (unit == null) {
            return dto.NO("单位不存在");
        }
        unit.setLongitude(dto.data.getBigDecimal("jingdu"));
        unit.setLatitude(dto.data.getBigDecimal("weidu"));
        unitDao.save(unit);
        return dto.OK();
    }

    @RequestMapping(value = "/mobileApp/set", method = {RequestMethod.GET, RequestMethod.POST})
    public Object appUpload(@RequestBody String text) throws Exception {
        AnYuanDto dto = AnYuanDto.from(text);

        String account = dto.data.getString("admin");
        Boolean receivedAll = dto.data.getBoolean("receivedAll");

        MobileApp mobileApp = mobileAppDao.findByAccount(account);
        if (mobileApp == null) {
            return dto.NO("找不到用户");
        }
        if (receivedAll != null) {
            mobileApp.setReceivedAll(receivedAll);
        }
        mobileAppDao.save(mobileApp);

        return dto.OK();
    }

    @RequestMapping(value = "/mobileApp/find", method = {RequestMethod.GET, RequestMethod.POST})
    public Object mobileAppInfo(@RequestBody String text) throws Exception {
        AnYuanDto dto = AnYuanDto.from(text);

        Set<MobileApp> mobileApps = new HashSet<>();
        Integer gettype = dto.data.getInteger("gettype");
        List<JSONObject> data = dto.data.getList("data",JSONObject.class);
        if (gettype == 1){
            List<String> accounts = data.stream().map(var -> var.getString("admin")).collect(Collectors.toList());
            mobileApps.addAll(mobileAppDao.findByAccountIn(accounts));
        }


        if (gettype == 2) {
            for (JSONObject appnum : data) {
                mobileApps.addAll(mobileAppDao.findScope(appnum.getBigDecimal("weidu"),appnum.getBigDecimal("jingdu"),0L,appnum.getLong("search")));
            }
        }

        List<AppCache> all = appOline.getAll();
        List<MobileApp> online = mobileApps.stream().filter(var->var.isOnline(all)).collect(Collectors.toList());
        List<MobileApp> unOnline = mobileApps.stream().filter(var-> !var.isOnline(all)).collect(Collectors.toList());

        Map<String,Object> ret = new HashMap<>();
        ret.put("onlinenum",online.size());
        ret.put("onlinedata",toMap(online));

        ret.put("unlinenum",unOnline.size());
        ret.put("unlineadmins",toMap(unOnline));

        return dto.OK(ret);
    }

    public List<Map<String, Object>> toMap(List<MobileApp> mobileApps){
        List<Map<String,Object>> apps = new ArrayList<>();
        for (MobileApp mobileApp : mobileApps) {
            HashMap<String, Object> admin = new HashMap<>();

            admin.put("admin",mobileApp.getAccount());
            admin.put("name",mobileApp.getName());
            admin.put("sex",mobileApp.getSex());
            admin.put("tel",mobileApp.getTel());
            admin.put("jobcode",mobileApp.getJob());
            admin.put("jingdu",mobileApp.getLongitude());
            admin.put("weidu",mobileApp.getLatitude());

            admin.put("date",mobileApp.getLocationAt());
            apps.add(admin);
        }
        return apps;
    }


    @RequestMapping(value = "/test", method = {RequestMethod.GET, RequestMethod.POST})
    public List<Object> test(@RequestBody String data) throws Exception {
        List<Object> ret = new ArrayList<>();
        ret.add(data);
        ret.add(trim(data));
        return ret;
    }

    public JSONObject trim(String text) throws Exception {
        text = text.trim();
        text = URLDecoder.decode(text, "UTF-8");
        if (text.endsWith("=")) {
            text = text.substring(0, text.length() - 1);
        }
        return JSONObject.parseObject(text);
    }

}
